package com.mvc.framework.scheduling;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;

import org.apache.commons.logging.Log;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.jdbcjobstore.oracle.OracleDelegate;
import org.quartz.utils.Key;

import com.mvc.ProjectConstants;

public class ExtendOracleJobStoreDelegate extends OracleDelegate {

	public ExtendOracleJobStoreDelegate(Log logger, String tablePrefix,
			String instanceId) {
		super(logger, tablePrefix, instanceId);
	}

	private static final String COL_PROJECT_NAME = "PROJECT_NAME";

	String SELECT_TRIGGERS_IN_STATE = "SELECT " + COL_TRIGGER_NAME + ", "
			+ COL_TRIGGER_GROUP + " FROM " + TABLE_PREFIX_SUBST
			+ TABLE_TRIGGERS + " WHERE " + COL_TRIGGER_STATE + " = ? AND "
			+ COL_PROJECT_NAME + " = ?";

	public Key[] selectTriggersInState(Connection conn, String state)
			throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = conn.prepareStatement(rtp(SELECT_TRIGGERS_IN_STATE));
			ps.setString(1, state);
			ps.setString(2, ProjectConstants.PROJECT_NAME);
			rs = ps.executeQuery();

			ArrayList list = new ArrayList();
			while (rs.next()) {
				list.add(new Key(rs.getString(1), rs.getString(2)));
			}

			Key[] sArr = (Key[]) list.toArray(new Key[list.size()]);
			return sArr;
		} finally {
			closeResultSet(rs);
			closeStatement(ps);
		}
	}

	String SELECT_MISFIRED_TRIGGERS_IN_STATE = "SELECT " + COL_TRIGGER_NAME
			+ ", " + COL_TRIGGER_GROUP + " FROM " + TABLE_PREFIX_SUBST
			+ TABLE_TRIGGERS + " WHERE " + COL_NEXT_FIRE_TIME + " < ? AND "
			+ COL_TRIGGER_STATE + " = ? AND " + COL_PROJECT_NAME + " = ?";

	public Key[] selectMisfiredTriggersInState(Connection conn, String state,
			long ts) throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = conn.prepareStatement(rtp(SELECT_MISFIRED_TRIGGERS_IN_STATE));
			ps.setBigDecimal(1, new BigDecimal(String.valueOf(ts)));
			ps.setString(2, state);
			ps.setString(3, ProjectConstants.PROJECT_NAME);
			rs = ps.executeQuery();

			ArrayList list = new ArrayList();
			while (rs.next()) {
				String triggerName = rs.getString(COL_TRIGGER_NAME);
				String groupName = rs.getString(COL_TRIGGER_GROUP);
				list.add(new Key(triggerName, groupName));
			}
			Object[] oArr = list.toArray();
			Key[] kArr = new Key[oArr.length];
			System.arraycopy(oArr, 0, kArr, 0, oArr.length);
			return kArr;
		} finally {
			closeResultSet(rs);
			closeStatement(ps);
		}
	}

	String SELECT_MISFIRED_TRIGGERS_IN_STATES = "SELECT TRIGGER_NAME, TRIGGER_GROUP "
			+ " FROM {0}TRIGGERS WHERE NEXT_FIRE_TIME < ? AND ((TRIGGER_STATE = ?) OR (TRIGGER_STATE = ?)) AND "
			+ COL_PROJECT_NAME + " = ?";

	public boolean selectMisfiredTriggersInStates(Connection conn,
			String state1, String state2, long ts, int count, List resultList)
			throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = conn.prepareStatement(rtp(SELECT_MISFIRED_TRIGGERS_IN_STATES));
			ps.setBigDecimal(1, new BigDecimal(String.valueOf(ts)));
			ps.setString(2, state1);
			ps.setString(3, state2);
			ps.setString(4, ProjectConstants.PROJECT_NAME);
			rs = ps.executeQuery();

			boolean hasReachedLimit = false;
			while (rs.next() && (hasReachedLimit == false)) {
				if (resultList.size() == count) {
					hasReachedLimit = true;
				} else {
					String triggerName = rs.getString(COL_TRIGGER_NAME);
					String groupName = rs.getString(COL_TRIGGER_GROUP);
					resultList.add(new Key(triggerName, groupName));
				}
			}

			return hasReachedLimit;
		} finally {
			closeResultSet(rs);
			closeStatement(ps);
		}
	}

	String INSERT_TRIGGER = "INSERT INTO " + TABLE_PREFIX_SUBST
			+ TABLE_TRIGGERS + " (" + COL_TRIGGER_NAME + ", "
			+ COL_TRIGGER_GROUP + ", " + COL_JOB_NAME + ", " + COL_JOB_GROUP
			+ ", " + COL_IS_VOLATILE + ", " + COL_DESCRIPTION + ", "
			+ COL_NEXT_FIRE_TIME + ", " + COL_PREV_FIRE_TIME + ", "
			+ COL_TRIGGER_STATE + ", " + COL_TRIGGER_TYPE + ", "
			+ COL_START_TIME + ", " + COL_END_TIME + ", " + COL_CALENDAR_NAME
			+ ", " + COL_MISFIRE_INSTRUCTION + ", " + COL_JOB_DATAMAP + ", "
			+ COL_PRIORITY + ", " + COL_PROJECT_NAME + ") "
			+ " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";

    public int insertTrigger(Connection conn, Trigger trigger, String state,
            JobDetail jobDetail) throws SQLException, IOException {

        byte[] data = null;
        if (trigger.getJobDataMap().size() > 0) {
            data = serializeJobData(trigger.getJobDataMap()).toByteArray();
        }

        PreparedStatement ps = null;
        ResultSet rs = null;

        int insertResult = 0;

        try {
            ps = conn.prepareStatement(rtp(INSERT_TRIGGER));
            ps.setString(1, trigger.getName());
            ps.setString(2, trigger.getGroup());
            ps.setString(3, trigger.getJobName());
            ps.setString(4, trigger.getJobGroup());
            setBoolean(ps, 5, trigger.isVolatile());
            ps.setString(6, trigger.getDescription());
            ps.setBigDecimal(7, new BigDecimal(String.valueOf(trigger
                    .getNextFireTime().getTime())));
            long prevFireTime = -1;
            if (trigger.getPreviousFireTime() != null) {
                prevFireTime = trigger.getPreviousFireTime().getTime();
            }
            ps.setBigDecimal(8, new BigDecimal(String.valueOf(prevFireTime)));
            ps.setString(9, state);
            if (trigger instanceof SimpleTrigger && ((SimpleTrigger)trigger).hasAdditionalProperties() == false ) {
                ps.setString(10, TTYPE_SIMPLE);
            } else if (trigger instanceof CronTrigger && ((CronTrigger)trigger).hasAdditionalProperties() == false ) {
                ps.setString(10, TTYPE_CRON);
            } else {
                ps.setString(10, TTYPE_BLOB);
            }
            ps.setBigDecimal(11, new BigDecimal(String.valueOf(trigger
                    .getStartTime().getTime())));
            long endTime = 0;
            if (trigger.getEndTime() != null) {
                endTime = trigger.getEndTime().getTime();
            }
            ps.setBigDecimal(12, new BigDecimal(String.valueOf(endTime)));
            ps.setString(13, trigger.getCalendarName());
            ps.setInt(14, trigger.getMisfireInstruction());
            ps.setBinaryStream(15, null, 0);
            ps.setInt(16, trigger.getPriority());
            ps.setString(17, ProjectConstants.PROJECT_NAME);

            insertResult = ps.executeUpdate();

            if(data != null) {
                ps.close();

                ps = conn
                    .prepareStatement(rtp(UPDATE_ORACLE_TRIGGER_JOB_DETAIL_EMPTY_BLOB));
                ps.setString(1, trigger.getName());
                ps.setString(2, trigger.getGroup());
                ps.executeUpdate();
                ps.close();

                ps = conn.prepareStatement(rtp(SELECT_ORACLE_TRIGGER_JOB_DETAIL_BLOB));
                ps.setString(1, trigger.getName());
                ps.setString(2, trigger.getGroup());

                rs = ps.executeQuery();

                int res = 0;

                Blob dbBlob = null;
                if (rs.next()) {
                    dbBlob = writeDataToBlob(rs, 1, data);
                } else {
                    return res;
                }

                rs.close();
                ps.close();

                ps = conn.prepareStatement(rtp(UPDATE_ORACLE_TRIGGER_JOB_DETAIL_BLOB));
                ps.setBlob(1, dbBlob);
                ps.setString(2, trigger.getName());
                ps.setString(3, trigger.getGroup());

                ps.executeUpdate();
            }

        } finally {
            closeResultSet(rs);
            closeStatement(ps);
        }

        if (insertResult > 0) {
            String[] trigListeners = trigger.getTriggerListenerNames();
            for (int i = 0; trigListeners != null && i < trigListeners.length; i++) {
                insertTriggerListener(conn, trigger, trigListeners[i]);
            }
        }

        return insertResult;
    }

	String SELECT_TRIGGER = "SELECT *" + " FROM " + TABLE_PREFIX_SUBST
			+ TABLE_TRIGGERS + " WHERE " + COL_TRIGGER_NAME + " = ? AND "
			+ COL_TRIGGER_GROUP + " = ? AND " + COL_PROJECT_NAME + " = ?";

	public Trigger selectTrigger(Connection conn, String triggerName,
			String groupName) throws SQLException, ClassNotFoundException,
			IOException {
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			Trigger trigger = null;

			ps = conn.prepareStatement(rtp(SELECT_TRIGGER));
			ps.setString(1, triggerName);
			ps.setString(2, groupName);
			ps.setString(3, ProjectConstants.PROJECT_NAME);
			rs = ps.executeQuery();

			if (rs.next()) {
				String jobName = rs.getString(COL_JOB_NAME);
				String jobGroup = rs.getString(COL_JOB_GROUP);
				boolean volatility = getBoolean(rs, COL_IS_VOLATILE);
				String description = rs.getString(COL_DESCRIPTION);
				long nextFireTime = rs.getLong(COL_NEXT_FIRE_TIME);
				long prevFireTime = rs.getLong(COL_PREV_FIRE_TIME);
				String triggerType = rs.getString(COL_TRIGGER_TYPE);
				long startTime = rs.getLong(COL_START_TIME);
				long endTime = rs.getLong(COL_END_TIME);
				String calendarName = rs.getString(COL_CALENDAR_NAME);
				int misFireInstr = rs.getInt(COL_MISFIRE_INSTRUCTION);
				int priority = rs.getInt(COL_PRIORITY);

				Map map = null;
				if (canUseProperties()) {
					map = getMapFromProperties(rs);
				} else {
					map = (Map) getObjectFromBlob(rs, COL_JOB_DATAMAP);
				}

				Date nft = null;
				if (nextFireTime > 0) {
					nft = new Date(nextFireTime);
				}

				Date pft = null;
				if (prevFireTime > 0) {
					pft = new Date(prevFireTime);
				}
				Date startTimeD = new Date(startTime);
				Date endTimeD = null;
				if (endTime > 0) {
					endTimeD = new Date(endTime);
				}

				rs.close();
				ps.close();

				if (triggerType.equals(TTYPE_SIMPLE)) {
					ps = conn.prepareStatement(rtp(SELECT_SIMPLE_TRIGGER));
					ps.setString(1, triggerName);
					ps.setString(2, groupName);
					rs = ps.executeQuery();

					if (rs.next()) {
						int repeatCount = rs.getInt(COL_REPEAT_COUNT);
						long repeatInterval = rs.getLong(COL_REPEAT_INTERVAL);
						int timesTriggered = rs.getInt(COL_TIMES_TRIGGERED);

						SimpleTrigger st = new SimpleTrigger(triggerName,
								groupName, jobName, jobGroup, startTimeD,
								endTimeD, repeatCount, repeatInterval);
						st.setCalendarName(calendarName);
						st.setMisfireInstruction(misFireInstr);
						st.setTimesTriggered(timesTriggered);
						st.setVolatility(volatility);
						st.setNextFireTime(nft);
						st.setPreviousFireTime(pft);
						st.setDescription(description);
						st.setPriority(priority);
						if (null != map) {
							st.setJobDataMap(new JobDataMap(map));
						}
						trigger = st;
					}
				} else if (triggerType.equals(TTYPE_CRON)) {
					ps = conn.prepareStatement(rtp(SELECT_CRON_TRIGGER));
					ps.setString(1, triggerName);
					ps.setString(2, groupName);
					rs = ps.executeQuery();

					if (rs.next()) {
						String cronExpr = rs.getString(COL_CRON_EXPRESSION);
						String timeZoneId = rs.getString(COL_TIME_ZONE_ID);

						CronTrigger ct = null;
						try {
							TimeZone timeZone = null;
							if (timeZoneId != null) {
								timeZone = TimeZone.getTimeZone(timeZoneId);
							}
							ct = new CronTrigger(triggerName, groupName,
									jobName, jobGroup, startTimeD, endTimeD,
									cronExpr, timeZone);
						} catch (Exception neverHappens) {
							// expr must be valid, or it never would have
							// gotten to the store...
						}
						if (null != ct) {
							ct.setCalendarName(calendarName);
							ct.setMisfireInstruction(misFireInstr);
							ct.setVolatility(volatility);
							ct.setNextFireTime(nft);
							ct.setPreviousFireTime(pft);
							ct.setDescription(description);
							ct.setPriority(priority);
							if (null != map) {
								ct.setJobDataMap(new JobDataMap(map));
							}
							trigger = ct;
						}
					}
				} else if (triggerType.equals(TTYPE_BLOB)) {
					ps = conn.prepareStatement(rtp(SELECT_BLOB_TRIGGER));
					ps.setString(1, triggerName);
					ps.setString(2, groupName);
					rs = ps.executeQuery();

					if (rs.next()) {
						trigger = (Trigger) getObjectFromBlob(rs, COL_BLOB);
					}
				} else {
					throw new ClassNotFoundException("class for trigger type '"
							+ triggerType + "' not found.");
				}
			}

			return trigger;
		} finally {
			closeResultSet(rs);
			closeStatement(ps);
		}
	}

//	String SELECT_NUM_TRIGGERS = "SELECT COUNT(" + COL_TRIGGER_NAME + ") "
//			+ " FROM " + TABLE_PREFIX_SUBST + TABLE_TRIGGERS;
//
//	String SELECT_NUM_TRIGGERS_IN_GROUP = "SELECT COUNT(" + COL_TRIGGER_NAME
//			+ ") " + " FROM " + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE "
//			+ COL_TRIGGER_GROUP + " = ?";
//
//	String SELECT_TRIGGER_GROUPS = "SELECT DISTINCT(" + COL_TRIGGER_GROUP
//			+ ") FROM " + TABLE_PREFIX_SUBST + TABLE_TRIGGERS;

	String SELECT_TRIGGERS_IN_GROUP = "SELECT " + COL_TRIGGER_NAME + " FROM "
			+ TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE "
			+ COL_TRIGGER_GROUP + " = ? AND " + COL_PROJECT_NAME + " = ?";

	public String[] selectTriggersInGroup(Connection conn, String groupName)
			throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = conn.prepareStatement(rtp(SELECT_TRIGGERS_IN_GROUP));
			ps.setString(1, groupName);
			ps.setString(2, ProjectConstants.PROJECT_NAME);
			rs = ps.executeQuery();

			ArrayList list = new ArrayList();
			while (rs.next()) {
				list.add(rs.getString(1));
			}

			Object[] oArr = list.toArray();
			String[] sArr = new String[oArr.length];
			System.arraycopy(oArr, 0, sArr, 0, oArr.length);
			return sArr;
		} finally {
			closeResultSet(rs);
			closeStatement(ps);
		}
	}

	String SELECT_TRIGGER_FOR_FIRE_TIME = "SELECT " + COL_TRIGGER_NAME + ", "
			+ COL_TRIGGER_GROUP + " FROM " + TABLE_PREFIX_SUBST
			+ TABLE_TRIGGERS + " WHERE " + COL_TRIGGER_STATE + " = ? AND "
			+ COL_NEXT_FIRE_TIME + " = ? AND " + COL_PROJECT_NAME + " = ?";

	public Key selectTriggerForFireTime(Connection conn, long fireTime)
			throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(rtp(SELECT_TRIGGER_FOR_FIRE_TIME));
			ps.setString(1, STATE_WAITING);
			ps.setBigDecimal(2, new BigDecimal(String.valueOf(fireTime)));
			ps.setString(3, ProjectConstants.PROJECT_NAME);
			rs = ps.executeQuery();

			if (rs.next()) {
				return new Key(rs.getString(COL_TRIGGER_NAME), rs
						.getString(COL_TRIGGER_GROUP));
			} else {
				return null;
			}
		} finally {
			closeResultSet(rs);
			closeStatement(ps);
		}
	}

	 String UPDATE_TRIGGER_GROUP_STATE_FROM_STATES = "UPDATE "
         + TABLE_PREFIX_SUBST
         + TABLE_TRIGGERS
         + " SET "
         + COL_TRIGGER_STATE
         + " = ?"
         + " WHERE "
         + COL_TRIGGER_GROUP
         + " = ? AND ("
         + COL_TRIGGER_STATE
         + " = ? OR "
         + COL_TRIGGER_STATE
         + " = ? OR "
         + COL_TRIGGER_STATE + " = ?)"
         + " AND " + COL_PROJECT_NAME + " = ?";

	  public int updateTriggerGroupStateFromOtherStates(Connection conn,
	            String groupName, String newState, String oldState1,
	            String oldState2, String oldState3) throws SQLException {
	        PreparedStatement ps = null;

	        try {
	            ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_GROUP_STATE_FROM_STATES));
	            ps.setString(1, newState);
	            ps.setString(2, groupName);
	            ps.setString(3, oldState1);
	            ps.setString(4, oldState2);
	            ps.setString(5, oldState3);
	            ps.setString(6, ProjectConstants.PROJECT_NAME);

	            return ps.executeUpdate();
	        } finally {
	            closeStatement(ps);
	        }
	    }

	    String UPDATE_TRIGGER_GROUP_STATE_FROM_STATE = "UPDATE "
            + TABLE_PREFIX_SUBST
            + TABLE_TRIGGERS
            + " SET "
            + COL_TRIGGER_STATE
            + " = ?"
            + " WHERE "
            + COL_TRIGGER_GROUP
            + " = ? AND "
            + COL_TRIGGER_STATE + " = ?"
            + " AND " + COL_PROJECT_NAME + " = ?";

	    public int updateTriggerGroupStateFromOtherState(Connection conn,
	            String groupName, String newState, String oldState)
	        throws SQLException {
	        PreparedStatement ps = null;

	        try {
	            ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_GROUP_STATE_FROM_STATE));
	            ps.setString(1, newState);
	            ps.setString(2, groupName);
	            ps.setString(3, oldState);
	            ps.setString(4, ProjectConstants.PROJECT_NAME);
	            return ps.executeUpdate();
	        } finally {
	            closeStatement(ps);
	        }
	    }

	    String UPDATE_TRIGGER_STATE = "UPDATE "
            + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " SET " + COL_TRIGGER_STATE
            + " = ?" + " WHERE " + COL_TRIGGER_NAME + " = ? AND "
            + COL_TRIGGER_GROUP + " = ?"
            + " AND " + COL_PROJECT_NAME + " = ?";

	    public int updateTriggerState(Connection conn, String triggerName,
	            String groupName, String state) throws SQLException {
	        PreparedStatement ps = null;

	        try {
	            ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_STATE));
	            ps.setString(1, state);
	            ps.setString(2, triggerName);
	            ps.setString(3, groupName);
	            ps.setString(4, ProjectConstants.PROJECT_NAME);
	            return ps.executeUpdate();
	        } finally {
	            closeStatement(ps);
	        }
	    }


	    String UPDATE_TRIGGER_STATES_FROM_OTHER_STATES = "UPDATE "
            + TABLE_PREFIX_SUBST
            + TABLE_TRIGGERS
            + " SET "
            + COL_TRIGGER_STATE
            + " = ?"
            + " WHERE ("
            + COL_TRIGGER_STATE
            + " = ? OR "
            + COL_TRIGGER_STATE + " = ?) "
            + " AND " + COL_PROJECT_NAME + " = ?";

	    public int updateTriggerStatesFromOtherStates(Connection conn,
	            String newState, String oldState1, String oldState2)
	        throws SQLException {
	        PreparedStatement ps = null;

	        try {
	            ps = conn
	                    .prepareStatement(rtp(UPDATE_TRIGGER_STATES_FROM_OTHER_STATES));
	            ps.setString(1, newState);
	            ps.setString(2, oldState1);
	            ps.setString(3, oldState2);
	            ps.setString(4, ProjectConstants.PROJECT_NAME);
	            return ps.executeUpdate();
	        } finally {
	            closeStatement(ps);
	        }
	    }

	    String UPDATE_TRIGGER_STATE_FROM_OTHER_STATES_BEFORE_TIME = "UPDATE "
            + TABLE_PREFIX_SUBST
            + TABLE_TRIGGERS
            + " SET "
            + COL_TRIGGER_STATE
            + " = ?"
            + " WHERE ("
            + COL_TRIGGER_STATE
            + " = ? OR "
            + COL_TRIGGER_STATE + " = ?) AND " + COL_NEXT_FIRE_TIME + " < ?";


	    public int updateTriggerStateFromOtherStatesBeforeTime(Connection conn,
	            String newState, String oldState1, String oldState2, long time)
	        throws SQLException {
	        PreparedStatement ps = null;

	        try {
	            ps = conn
	                    .prepareStatement(rtp(UPDATE_TRIGGER_STATE_FROM_OTHER_STATES_BEFORE_TIME));
	            ps.setString(1, newState);
	            ps.setString(2, oldState1);
	            ps.setString(3, oldState2);
	            ps.setLong(4, time);

	            return ps.executeUpdate();
	        } finally {
	            closeStatement(ps);
	        }
	    }

	// String SELECT_JOB_DETAIL = "SELECT a.*" + " FROM "
	// + TABLE_PREFIX_SUBST + TABLE_JOB_DETAILS + " a,"
	// + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " b,"
	// + TABLE_PREFIX_SUBST + TABLE_FIRED_TRIGGERS + " c"
	// + " WHERE a." + COL_JOB_NAME + " = ? "
	// + " AND a." + COL_JOB_GROUP + " = ?"
	// + " AND a." + COL_JOB_NAME + " = b." + COL_JOB_NAME
	// + " AND b." + COL_TRIGGER_NAME + " = c." + COL_TRIGGER_NAME
	// + " AND c." + COL_INSTANCE_NAME + " = ? ";
	//
	// public JobDetail selectJobDetail(Connection conn, String jobName,
	// String groupName, ClassLoadHelper loadHelper)
	// throws ClassNotFoundException, IOException, SQLException {
	// PreparedStatement ps = null;
	// ResultSet rs = null;
	//
	// try {
	// ps = conn.prepareStatement(rtp(SELECT_JOB_DETAIL));
	// ps.setString(1, jobName);
	// ps.setString(2, groupName);
	// ps.setString(3, instanceId);
	// rs = ps.executeQuery();
	//
	// JobDetail job = null;
	//
	// if (rs.next()) {
	// job = new JobDetail();
	//
	// job.setName(rs.getString(COL_JOB_NAME));
	// job.setGroup(rs.getString(COL_JOB_GROUP));
	// job.setDescription(rs.getString(COL_DESCRIPTION));
	// job.setJobClass(loadHelper.loadClass(rs
	// .getString(COL_JOB_CLASS)));
	// job.setDurability(getBoolean(rs, COL_IS_DURABLE));
	// job.setVolatility(getBoolean(rs, COL_IS_VOLATILE));
	// job.setRequestsRecovery(getBoolean(rs, COL_REQUESTS_RECOVERY));
	//
	// Map map = null;
	// if (canUseProperties()) {
	// map = getMapFromProperties(rs);
	// } else {
	// map = (Map) getObjectFromBlob(rs, COL_JOB_DATAMAP);
	// }
	//
	// if (null != map) {
	// job.setJobDataMap(new JobDataMap(map));
	// }
	// }
	//
	// return job;
	// } finally {
	// closeResultSet(rs);
	// closeStatement(ps);
	// }
	// }

	/**
	 * build Map from java.util.Properties encoding.
	 */
	private Map getMapFromProperties(ResultSet rs)
			throws ClassNotFoundException, IOException, SQLException {
		Map map;
		InputStream is = (InputStream) getJobDetailFromBlob(rs, COL_JOB_DATAMAP);
		if (is == null) {
			return null;
		}
		Properties properties = new Properties();
		if (is != null) {
			try {
				properties.load(is);
			} finally {
				is.close();
			}
		}
		map = convertFromProperty(properties);
		return map;
	}
}
